-- $LastChangedDate: 2007-04-30 17:24:59 +0200 (Mon, 30 Apr 2007) $
-- $LastChangedRevision: 72 $
-- $LastChangedBy: david $

with AUnit.Test_Cases.Registration;
use AUnit.Test_Cases.Registration;

with AUnit.Assertions; use AUnit.Assertions;

with Integer_Lists; use Integer_Lists;
with Character_Lists; use Character_Lists;

package body test_list is

   procedure Test_add_to_int_list  (R: in out AUnit.Test_Cases.Test_Case'Class);
   procedure Test_add_to_char_list (R: in out AUnit.Test_Cases.Test_Case'Class);
   procedure Test_get_value_of_empty_list (R: in out AUnit.Test_Cases.Test_Case'Class);
   procedure Test_insert_into_unassigned_iterator (R: in out AUnit.Test_Cases.Test_Case'Class);
   procedure Test_delete_elements (R: in out AUnit.Test_Cases.Test_Case'Class);
   procedure Test_update_element (R: in out AUnit.Test_Cases.Test_Case'Class);



   procedure Set_Up (T : in out Test_Case) is
   begin
      --  Do any necessary set ups.  If there are none,
      --  omit from both spec and body, as a default
      --  version is provided in Test_Cases.
      null;
   end Set_Up;



   procedure Tear_Down (T : in out Test_Case) is
   begin
      --  Do any necessary cleanups, so the next test
      --  has a clean environment.  If there is no
      --  cleanup, omit spec and body, as default is
      --  provided in Test_Cases.
      null;
   end Tear_Down;



   --  Add some integers to a integer list
   procedure Test_add_to_int_list (R : in out AUnit.Test_Cases.Test_Case'Class) is
      l: Integer_Lists.List_Type;
      I: Integer_Lists.List_Iterator;
      k: integer;
      first_value: constant integer := 1;
      last_value: constant integer := 10;
   begin

      I := Integer_Lists.First(l);
      -- null
      --  ^-- I

      for v in first_value..last_value loop
         Integer_Lists.Insert(I, v);
      end loop;
      -- first_value ... last_value null
      --                             ^-- I

      k := first_value;
      I := Integer_Lists.First(l);
      while I /= Integer_Lists.Last(l) loop
         Assert (k = Integer_Lists.Value(I), "Wrong element inside integer " &
                     "list: expected" & Integer'Image(k) & " but found" &
                     Integer'Image(Integer_Lists.Value(I)));
         I := Integer_Lists.Succ(I);
         k := k + 1;
      end loop;
   end Test_add_to_int_list;



   -- Add some characters to a character list
   procedure Test_add_to_char_list (R : in out AUnit.Test_Cases.Test_Case'Class) is
      l: Character_Lists.List_Type;
      I: Character_Lists.List_Iterator;
      c: character;
   begin
      I := Character_Lists.First(l);
      -- null
      --  ^-- I
      Character_Lists.Insert(I, 'x');
      --  x null
      --     ^-- I

      Character_Lists.Insert(I, 'y');
      --  x y null
      --       ^-- I

      Character_Lists.Insert(I, 'z');
      --  x y z null
      --         ^-- I

      I := Character_Lists.First(l);
      c := Character_Lists.Value(I);
      Assert(c = 'x', "Wrong element inside character list: " &
               "expected 'x' but found " & Character'Image(c));

      I := Character_Lists.Succ(I);
      c := Character_Lists.Value(I);
      Assert(c = 'y', "Wrong element inside character list: " &
               "expected 'y' but found" & Character'Image(c));

      I := Character_Lists.Succ(I);
      c := Character_Lists.Value(I);
      Assert(c = 'z', "Wrong element inside character list: " &
               "expected 'z' but found" & Character'Image(c));

   end Test_add_to_char_list;



   procedure Test_get_value_of_empty_list (R: in out AUnit.Test_Cases.Test_Case'Class) is
      l: Integer_Lists.List_Type;
      I: Integer_Lists.List_Iterator;
      j: Integer;
   begin
      I := Integer_Lists.First(l);
      j := Integer_Lists.Value(I); -- l is empty, raise exception
      Assert(false, "No exception raised");
   exception
      when Integer_Lists.List_Error =>
         -- Test passed
         null;
   end Test_get_value_of_empty_list;



   procedure Test_insert_into_unassigned_iterator (R: in out AUnit.Test_Cases.Test_Case'Class) is
      I: Integer_Lists.List_Iterator;
   begin
      Integer_Lists.Insert(I, 42);
      Assert(false, "No exception raised");
   exception
      when Integer_Lists.List_Error =>
         -- Test passed
         null;
   end Test_insert_into_unassigned_iterator;



   procedure Test_delete_elements (R: in out AUnit.Test_Cases.Test_Case'Class) is
      l: Integer_Lists.List_Type;
      I: Integer_Lists.List_Iterator;
   begin
      -- Insertamos dos elementos

      I := Integer_Lists.First(l);
      --  null
      --   ^-- I

      Integer_Lists.Insert(I, 42); 
      -- 42 null
      --      ^-- I
   
      Integer_Lists.Insert(I, 60);
      -- 42 60 null
      --         ^-- I

      I := Integer_Lists.First(l);
      -- 42 60 null
      --  ^-- I

      Assert (Integer_Lists.Value(I) = 42, "Wrong element inside integer " &
                  "list: expected 42 but found" &
                  Integer'Image(Integer_Lists.Value(I)));

      -- Borramos
      Integer_Lists.Delete(I);
      --     60 null
      --  ^-- I

      I := Integer_Lists.First(l);
      -- 60 null
      --  ^-- I
      Assert (Integer_Lists.Value(I) = 60, "Wrong element inside integer " &
                  "list: expected 60 but found" &
                  Integer'Image(Integer_Lists.Value(I)));

      -- Borramos
      Integer_Lists.Delete(I);
      --     null
      --  ^-- I
      Assert (Integer_Lists.First(l) = Integer_Lists.Last(l), "First doesn't equal last");

   end Test_delete_elements;


   procedure Test_update_element (R: in out AUnit.Test_Cases.Test_Case'Class) is
      l: Integer_Lists.List_Type;
      I: Integer_Lists.List_Iterator;
      k: Integer;
   begin
      I := Integer_Lists.First(l);
      --  null
      --   ^-- I

      Integer_Lists.Insert(I, 42); 
      -- 42 null
      --      ^-- I

      I := Integer_Lists.First(l);
      -- 42 null
      --  ^-- I

      k := Integer_Lists.Value(I);
      k := k + 1;

      I := Integer_Lists.First(l);
      Integer_Lists.Update(I, k);
      -- 43 null
      --  ^-- I
      k := Integer_Lists.Value(I);
      Assert (k = 43, "Element not updated correctly");

   end Test_update_element;

   --  Register test routines to call:
   procedure Register_Tests (T : in out Test_Case) is
   begin
      --  Repeat for each test routine.
      Register_Routine (T, Test_add_to_int_list'Access, 
                        "Addition of elements to integer list");

      Register_Routine (T, Test_add_to_char_list'Access, 
                        "Addition of elements to character list");

      Register_Routine (T, Test_get_value_of_empty_list'Access, 
                        "Get first of empty list");
      Register_Routine (T, Test_insert_into_unassigned_iterator'Access,
                        "Try to insert into a iterator not pointing to any list");
      Register_Routine (T, Test_delete_elements'Access,
                        "Delete elements of a list");
      Register_Routine (T, Test_update_element'Access,
                        "Modify element in a list");
   end Register_Tests;



   --  Identifier of test case:
   function Name (T : Test_Case) return String_Access is
   begin
      return new String'("Test list package");
   end Name;

end test_list;
